home *** CD-ROM | disk | FTP | other *** search
- #include "fpse.h"
-
- #undef PRINTF
- #undef rs
- #undef rt
- #undef rd
-
- #define PRINTF if (1==0) printf
- #define rs rsno*4
- #define rt rtno*4
- #define rd rdno*4
-
- #define idxCPR0 35*4
- #define idxCCR0 (35+32)*4
- #define idxCPR2 (35+64)*4
- #define idxCCR2 (35+96)*4
- #define rPC 32*4
- #define idxrLO 33*4
- #define idxrHI 34*4
-
- #define PP 0 /* Pentium optimize */
-
- #define COMPILERSIZE (1024*1024)
-
- typedef void (*funcptr)();
-
- /* runtime function */
-
- int breakpoint = 0; /* 0x1a1c; */
- int writebreak = 0; /*xa000e28c;*/
- /*
- void watch(void)
- {
- static char *regname[32] = {
- "zero","at","v0","v1","a0","a1","a2","a3",
- "t0","t1","t2","t3","t4","t5","t6","t7",
- "s0","s1","s2","s3","s4","s5","s6","s7",
- "t8","t9","k0","k1","gp","sp","fp","ra"
- };
-
- int i;
- for(i=0;i<32;i++)
- printf("%-4s = %08x ",regname[i],(int)reg.r[i]);
- printf("\n");
- }
- */
- static void swl(UINT32 adr,UINT32 r)
- {
- UINT32 data = read32(adr&~3);
- switch(adr&3) {
- #if TARGET_BIG_ENDIAN
- case 0: data = r; break;
- case 1: data = (data & 0xff000000) | (r>> 8); break;
- case 2: data = (data & 0xffff0000) | (r>>16); break;
- case 3: data = (data & 0xffffff00) | (r>>24); break;
- #else
- case 3: data = r; break;
- case 2: data = (data & 0xff000000) | (r>> 8); break;
- case 1: data = (data & 0xffff0000) | (r>>16); break;
- case 0: data = (data & 0xffffff00) | (r>>24); break;
- #endif
- }
- write32(adr&~3,data);
- }
-
- static void swr(UINT32 adr,UINT32 r)
- {
- UINT32 data = read32(adr&~3);
- switch(adr&3) {
- #if TARGET_BIG_ENDIAN
- case 0: data = (data & 0x00ffffff) | (r<<24); break;
- case 1: data = (data & 0x0000ffff) | (r<<16); break;
- case 2: data = (data & 0x000000ff) | (r<< 8); break;
- case 3: data = r; break;
- #else
- case 3: data = (data & 0x00ffffff) | (r<<24); break;
- case 2: data = (data & 0x0000ffff) | (r<<16); break;
- case 1: data = (data & 0x000000ff) | (r<< 8); break;
- case 0: data = r; break;
- #endif
- }
- write32(adr&~3,data);
- }
-
- static UINT32 lwl(UINT32 adr,UINT32 r)
- {
- UINT32 data = read32(adr&~3);
- switch(adr&3) {
- #if TARGET_BIG_ENDIAN
- case 0: r = data; break;
- case 1: r = (r & 0x000000ff) | (data<< 8); break;
- case 2: r = (r & 0x0000ffff) | (data<<16); break;
- case 3: r = (r & 0x00ffffff) | (data<<24); break;
- #else
- case 3: r = data; break;
- case 2: r = (r & 0x000000ff) | (data<< 8); break;
- case 1: r = (r & 0x0000ffff) | (data<<16); break;
- case 0: r = (r & 0x00ffffff) | (data<<24); break;
- #endif
- }
- return r;
- }
-
- static UINT32 lwr(UINT32 adr,UINT32 r)
- {
- UINT32 data = read32(adr&~3);
- switch(adr&3) {
- #if TARGET_BIG_ENDIAN
- case 0: r = (r & 0xffffff00) | (data>>24); break;
- case 1: r = (r & 0xffff0000) | (data>>16); break;
- case 2: r = (r & 0xff000000) | (data>> 8); break;
- case 3: r = data; break;
- #else
- case 3: r = (r & 0xffffff00) | (data>>24); break;
- case 2: r = (r & 0xffff0000) | (data>>16); break;
- case 1: r = (r & 0xff000000) | (data>> 8); break;
- case 0: r = data; break;
- #endif
- }
- return r;
- }
-
- #define NOT_IMPREMENT(cd) printf("not imprement %s: %08x\n",cd,(int)code);
-
- static int lastax = -1;
-
- #define MAXMEMBLKS 1024
-
- static UINT32 MemBlocksIdx=0;
- static UINT32 MemBlocks[MAXMEMBLKS*2];
- static UINT8 *compilebuf;
- static UINT32 *realpc;
- static UINT8 *pcptr;
- static char endflg;
- static UINT8 exitflg=0;
-
- #define COMPILED(adr) realpc[( (adr<0xbfc00000) ? \
- ((adr>=0x1f000000 && adr<0x1f020000) ? \
- (adr-0x1f000000+0x280000):(adr&0x1fffff)) : \
- (adr-0xbfc00000+0x200000) )/4]
-
- static int SearchFreeSlot()
- {
- int x;
-
- for (x=0;x<MAXMEMBLKS;x++)
- if (MemBlocks[x*2] > 0x1FFFFFFF) return x;
-
- x = MemBlocksIdx;
- if (++MemBlocksIdx >= MAXMEMBLKS)
- MemBlocksIdx = 0;
- if (MemBlocks[x*2] < 0x1FFFFFFF)
- {
- memset(&COMPILED(MemBlocks[x*2]),0,
- MemBlocks[x*2+1] - MemBlocks[x*2] );
- }
-
- return x;
- }
-
- // int dmact = 0;
-
- void CompileFlush(UINT32 start, UINT32 end)
- {
- UINT32 x,mstart,mend;
-
- if (!compile) return;
-
- start &= 0x1FFFFFFF;
- end &= 0x1FFFFFFF;
- /*
- if (start == 0x1E000)
- {
- printf("Found CDMA - ACT=%08x-%08x\n",start,end);
-
- dmact= 1;
- }
- */
- for (x=0; x<MAXMEMBLKS; x++)
- {
- mstart = MemBlocks[x*2];
- mend = MemBlocks[x*2+1];
- /*
- if (dmact) {
- printf("-> %03x) %08x-%08x\n", x, mstart, mend);
- if (x == 0x199)
- printf("reached limit \n");
- }
- */
- if ((start >= mstart && start <= mend) ||
- (mstart >= start && mstart <= end))
- {
- // printf("invalidate blk %08x-%08x\n",mstart,mend);
- MemBlocks[x*2] = 0xFFFFFFF;
- MemBlocks[x*2+1] = 0xFFFFFFF;
- memset(&COMPILED(mstart),0,mend-mstart);
- }
-
- }
- // dmact = 0;
- }
-
- UINT32 jmppc(UINT32 Pc)
- {
- int pc,startptr,x;
-
- if (update_hw()) {
- if ((SR&0x401)==0x401) {
- EPC = Pc;
- CAUSE = 0x400;
- SR = (SR & ~0x3f)| ((SR<<2)&0x3f);
- Pc = 0x80000080;
- }
- }
- switch(Pc) {
- case 0:
- // Oooppsss!! We need also to release everything
- // (otherwise DirectDraw will surely kill your PC!)
- printf("PC = 0 at $%08x\n",(int)(PC));
- if (exitflg)
- {
- hw_close();
- memfree();
- exit(-1);
- }
- break;
- case 0xa0:
- case 0xb0:
- case 0xc0:
- PC = Pc;
- biosprint(Pc);
- Pc = PC;
- break;
- case 0x80000080:
- PC = Pc;
- exception_handler();
- Pc = PC;
- break;
- }
-
- if (COMPILED(Pc)) return COMPILED(Pc);
-
- SETPC(Pc);
- endflg = 0;
- pc = Pc;
-
- if (pcptr > compilebuf+COMPILERSIZE-1024) // End-of-buffer is near
- { // Flush all
- memset(MemBlocks,0xFF,MAXMEMBLKS*2*sizeof(UINT32));
- memset(realpc,0,0x200000+0x80000+0x20000);
- pcptr = compilebuf;
- }
- startptr = (int)pcptr;
- x = SearchFreeSlot();
-
- while(!endflg)
- pc = compile1(pc);
-
- MemBlocks[x*2] = (Pc & 0x1FFFFFFF);
- MemBlocks[x*2+1] = (pc & 0x1FFFFFFF);
-
- PRINTF("compile : psx = %08x-%08x(%08x) pc = %08x-%08x(%08x)\n",
- (int)Pc,(int)pc,(int)(pc-Pc),(int)startptr,(int)pcptr,(int)(pcptr-startptr));
-
- return COMPILED(Pc);
- }
-
- #if 1
-
- #define GENCODE1(c0) *pcptr++=c0
- #define GENCODE2(c0,c1) pcptr[0]=c0;pcptr[1]=c1; pcptr+=2
- #define GENCODE3(c0,c1,c2) pcptr[0]=c0;pcptr[1]=c1;pcptr[2]=c2; pcptr+=3
- #define GENCODE4(c0,c1,c2,c3) pcptr[0]=c0;pcptr[1]=c1;pcptr[2]=c2;pcptr[3]=c3;pcptr+=4
- #define GENCODE1i(c0,imm) pcptr[0]=c0; *(long*)&pcptr[1]=(long)imm; pcptr+=5
- #define GENCODE2i(c0,c1,imm) pcptr[0]=c0;pcptr[1]=c1; *(long*)&pcptr[2]=(long)imm; pcptr+=6
- #define GENCODE3i(c0,c1,c2,imm) pcptr[0]=c0;pcptr[1]=c1;pcptr[2]=c2; *(long*)&pcptr[3]=(long)imm; pcptr+=7
-
- //#define DISASM(code,pc)
- #define DISASM if (verbose) disasm2
- static void disasm2(long code,long addr)
- {
- char buf[256];
- disasm(buf,code,addr);
- printf(";%08lx %08lx %s\n",addr,code,buf);
- }
-
- #else
-
- #define DISASM if (verbose) disasm2
- static void disasm2(long code,long addr)
- {
- char buf[256];
- disasm(buf,code,addr);
- printf(";%08lx %08lx %s\n",addr,code,buf);
- }
-
- static void GENCODE1(unsigned char c0)
- {
- PRINTF(" %p %02x ",pcptr,c0);
- *pcptr++=c0;
- }
- static void GENCODE2(unsigned char c0,unsigned char c1)
- {
- PRINTF(" %p %02x %02x ",pcptr,c0,c1);
- pcptr[0]=c0;pcptr[1]=c1;
- pcptr+=2;
- }
- static void GENCODE3(unsigned char c0,unsigned char c1,unsigned char c2)
- {
- PRINTF(" %p %02x %02x %02x ",pcptr,c0,c1,c2);
- pcptr[0]=c0;pcptr[1]=c1;pcptr[2]=c2;
- pcptr+=3;
- }
- static void GENCODE4(unsigned char c0,unsigned char c1,unsigned char c2,unsigned char c3)
- {
- PRINTF(" %p %02x %02x %02x %02x ",pcptr,c0,c1,c2,c3);
- pcptr[0]=c0;pcptr[1]=c1;pcptr[2]=c2;pcptr[3]=c3;
- pcptr+=4;
- }
-
- static void GENCODE1i(unsigned char c0,int imm)
- {
- PRINTF(" %p %02x %08x ",pcptr,c0,imm);
- pcptr[0]=c0;
- *(long*)&pcptr[1] = imm;
- pcptr+=5;
- }
- static void GENCODE2i(unsigned char c0,unsigned char c1,int imm)
- {
- PRINTF(" %p %02x %02x %08x ",pcptr,c0,c1,imm);
- pcptr[0]=c0;pcptr[1]=c1;
- *(long*)&pcptr[2] = imm;
- pcptr+=6;
- }
- static void GENCODE3i(unsigned char c0,unsigned char c1,unsigned char c2,int imm)
- {
- PRINTF(" %p %02x %02x %02x %08x ",pcptr,c0,c1,c2,imm);
- pcptr[0]=c0;pcptr[1]=c1;pcptr[2]=c2;
- *(long*)&pcptr[3] = imm;
- pcptr+=7;
- }
-
-
- #endif
-
- void compile_init(void)
- {
- compilebuf = malloc(COMPILERSIZE);
- realpc = malloc(0x200000+0x80000+0x20000);
- memset(realpc,0,0x200000+0x80000+0x20000);
- memset(MemBlocks,0xFF,MAXMEMBLKS*2*sizeof(UINT32));
- pcptr = compilebuf;
- }
-
- static void load_ax(int r)
- {
- if (!r) {
- GENCODE2(0x31,0xc0);
- PRINTF("xor eax,eax\n");
- } else {
- GENCODE3(0x8b,0x46,r);
- PRINTF("mov eax,[esi+%d]\n",r);
- }
- lastax = r;
- }
-
- #if 0
- static void load_dx(int r)
- {
- GENCODE3(0x8b,0x56,r);
- PRINTF("mov edx,[esi+%d]\n",r);
- }
- #endif
-
- static void store_ax(int r)
- {
- if (!r) return;
- GENCODE3(0x89,0x46,r);
- PRINTF("mov [esi+%d],eax\n",r);
- //isimm[r/4] = 0;
- lastax = r;
- }
-
- static void store_imm(int r,int imm)
- {
- GENCODE3i(0xc7,0x46,r,imm);
- PRINTF("mov dword [esi+%d],0%xh\n",r,imm);
- //isimm[r/4] = imm;
- lastax = -1;
- }
-
- static void push_imm(int imm)
- {
- GENCODE1i(0x68,imm);
- PRINTF("push 0%xh\n",imm);
- }
-
- static void push_ax(void)
- {
- GENCODE1(0x50);
- PRINTF("push eax\n");
- }
-
- static void push_r(int r)
- {
- if (!r) {
- load_ax(r);
- push_ax();
- } else {
- #if PP
- load_ax(r);
- push_ax();
- #else
- GENCODE3(0xff,0x76,r);
- PRINTF("push dword [esi+%d]\n",r);
- #endif
- }
- }
-
- /* ofset > 127 */
- static void load2_ax(int r)
- {
- GENCODE2i(0x8b,0x86,r);
- PRINTF("mov eax,[esi+%d]\n",r);
- }
-
- static void store2_ax(int r)
- {
- GENCODE2i(0x89,0x86,r);
- PRINTF("mov [esi+%d],eax\n",r);
- }
-
- static void store2_dx(int r)
- {
- GENCODE2i(0x89,0x96,r);
- PRINTF("mov [esi+%d],edx\n",r);
- }
-
- static void push2_r(int r)
- {
- GENCODE2i(0xff,0xb6,r);
- PRINTF("push dword [esi+%d]\n",r);
- }
-
-
- static void alu_i(UINT32 code,char *str,int op_r,int op_m)
- {
- int imm = immU;
- /*
- 05 ii ii ii ii add eax,imm
- 81 46 xx ii ii ii ii add dword [esi+rt],imm
- 25 ii ii ii ii and eax,imm
- 81 66 xx ii ii ii ii and dword [esi+rt],imm
- 0d ii ii ii ii or eax,imm
- 81 4e xx ii ii ii ii or dword [esi+rt],imm
- 35 ii ii ii ii xor eax,imm
- 81 76 xx ii ii ii ii xor dword [esi+rt],imm
- 3d ii ii ii ii cmp eax,imm
- 81 7e xx ii ii ii ii cmp dword [esi+rt],imm
- b8 ii ii ii ii mov eax,imm
- c7 46 xx ii ii ii ii mov dword [esi+rt],imm
- */
-
- /* 8b 46 xx mov eax,[esi+xx] */
- /* 89 46 xx mov [esi+xx],eax */
-
- if (!rt) return;
-
- if (rs) {
- if (rs==rt) {
- GENCODE3i(0x81,op_m,rs,imm);
- PRINTF("%s dword [esi+%d],0%xh\n",str,(int)rs,imm);
- /*if (rt==lastax)*/ lastax=-1;
- } else {
- load_ax(rs);
- GENCODE1i(op_r,imm);
- PRINTF("%s eax,%d\n",str,imm);
- store_ax(rt);
- }
- } else {
- store_imm(rt,imm);
- }
- }
-
- static void add_imm(int imm)
- {
- if (!imm) return;
-
- if (imm<-128 || imm>127) {
- GENCODE1i(0x05,imm);
- PRINTF("add eax,0%xh\n",imm);
- } else if (imm==1) {
- GENCODE1(0x40);
- PRINTF("inc eax\n");
- } else if (imm==-1) {
- GENCODE1(0x48);
- PRINTF("dec eax\n");
- } else {
- GENCODE3(0x8d,0x40,imm);
- PRINTF("lea eax,[eax+%d]\n",imm);
- }
- }
-
- static void add_i(UINT32 code)
- {
- /*
- 05 ii ii ii ii add eax,imm
- 81 46 xx ii ii ii ii add dword [esi+rt],imm
- */
- int imm = immS;
-
- if (!rt) return;
-
- if (rs) {
- if (rs==rt) {
- if (imm==1) {
- GENCODE3(0xff,0x46,rs);
- PRINTF("inc [esi+%d]\n",(int)rs);
- } else if (imm==-1) {
- GENCODE3(0xff,0x4e,rs);
- PRINTF("dec [esi+%d]\n",(int)rs);
- } else if (imm) {
- GENCODE3i(0x81,0x46,rs,imm);
- PRINTF("add dword [esi+%d],0%xh\n",(int)rs,imm);
- }
- } else {
- load_ax(rs);
- add_imm(imm);
- store_ax(rt);
- }
- } else {
- store_imm(rt,imm);
- }
- }
-
- static void alu_r(UINT32 code,char *str,int op_1,int op_2)
- {
- /*
- 03 46 xx add eax,[esi+rt]
- 01 46 xx add [esi+rt],eax
- 2b 46 xx sub eax,[esi+rt]
- 29 46 xx sub [esi+rt],eax
- 23 46 xx and eax,[esi+rt]
- 21 46 xx and [esi+rt],eax
- 0b 46 xx or eax,[esi+rt]
- 09 46 xx or [esi+rt],eax
- 33 46 xx xor eax,[esi+rt]
- 31 46 xx xor [esi+rt],eax
- 3b 46 xx cmp eax,[esi+rt]
- 39 46 xx cmp [esi+rt],eax
- */
- if (!rd) return;
-
- if (rs) {
- #if !PP
- if (rs==rd) {
- load_ax(rt);
- GENCODE3(op_2,0x46,rd);
- PRINTF("%s [esi+%d],eax\n",str,(int)rd);
- //isimm[rdno] = 0;
- return;
- } else
- #endif
- {
- load_ax(rs);
- if (rt) {
- GENCODE3(op_1,0x46,rt);
- PRINTF("%s eax,[esi+%d]\n",str,(int)rt);
- }
- }
- } else if (rt) {
- load_ax(rt);
- } else {
- store_imm(rd,0);
- return;
- }
- store_ax(rd);
- }
-
- static void subu_r(UINT32 code)
- {
- if (!rd) return;
-
- if (rs) {
- if (rs==rd) {
- if (rt) {
- load_ax(rt);
- GENCODE3(0x29,0x46,rd);
- PRINTF("sub [esi+%d],eax\n",(int)rd);
- //isimm[rdno] = 0;
- }
- return;
- }
- load_ax(rs);
- if (rt) {
- GENCODE3(0x2b,0x46,rt);
- PRINTF("sub eax,[esi+%d]\n",(int)rt);
- }
- } else if (rt) {
- load_ax(rt);
- GENCODE2(0xf7,0xd8);
- PRINTF("neg eax\n");
- } else {
- store_imm(rd,0);
- return;
- }
- store_ax(rd);
- }
-
- static void nor_r(UINT32 code)
- {
- /* f7 d0 not eax */
- if (!rd) return;
-
- if (rs) {
- load_ax(rs);
- if (rt) {
- GENCODE3(0x0b,0x46,rt);
- PRINTF("or eax,[esi+%d]\n",(int)rt);
- }
- } else if (rt) {
- load_ax(rt);
- } else {
- store_imm(rd,-1);
- return;
- }
- GENCODE2(0xf7,0xd0);
- PRINTF("not eax\n");
- store_ax(rd);
- }
-
- static void and_r(UINT32 code)
- {
- if (rd) {
- if (rs && rt) {
- load_ax(rs);
- GENCODE3(0x23,0x46,rt);
- PRINTF("and eax,[esi+%d]\n",(int)rt);
- store_ax(rd);
- } else {
- store_imm(rd,0);
- }
- }
- }
-
- /*
- 50 push eax
- ff 76 xx push dword [esi+xx]
- 40 inc eax
- 48 dec eax
- ff 46 xx inc dword [esi+rs]
- ff 4e xx dec dword [esi+rs]
- 8d 40 xx lea eax,[eax+imm]
- 31 c0 xor eax,eax
- f7 d8 neg eax
- */
-
- /*
- 9c pushf
- 9d popf
- e9 xx xx xx xx jmp
- eb xx jmp last
- 74 xx je last
- 75 xx jne last
- 7c xx jl last
- 7d xx jge last
- 7e xx jle last
- 7f xx jg last
- */
-
- static void cmp_i(UINT32 code,int imm)
- {
- GENCODE3i(0x81,0x7e,rs,imm);
- PRINTF("cmp [esi+%d],0%xh\n",(int)rs,imm);
- }
-
- static void cmp_r(UINT32 code)
- {
- if (!rt) { cmp_i(code,0); return; }
- load_ax(rs);
-
- GENCODE3(0x3b,0x46,rt);
- PRINTF("cmp eax,[esi+%d]\n",(int)rt);
- }
-
- static void compile2(UINT32 Pc)
- {
- FPSE_Flags |= IN_SLOT;
- compile1(Pc);
- FPSE_Flags &= ~IN_SLOT;
- }
-
- static void push_addr(UINT32 code)
- {
- if (rs==0) {
- push_imm(immS);
- } else
- if (immS) {
- load_ax(rs);
- add_imm(immS);
- push_ax();
- } else {
- push_r(rs);
- }
- }
-
- static void call(char *str,funcptr func,int argn)
- {
- /*
- b8 xx xx xx xx mov eax,xx
- ff e0 jmp eax
- ff 20 jmp [eax]
- ff d0 call eax
- ff 10 call [eax]
- ff 15 xx xx xx xx call [xx]
- e8 xx xx xx xx call xx (offset)
- 81 c4 xx xx xx xx add esp,2
- 8d 64 24 xx lea esp,[esp+2]
- */
-
- GENCODE1i(0xe8,(UINT32)func-(UINT32)(pcptr+5));
- PRINTF("call %s\n",str);
-
- /*
- 59 pop ecx
- 5a pop edx
- */
- lastax = -1;
- if (argn==4) {
- GENCODE1(0x5a);
- PRINTF("pop edx\n");
- } else if (argn==8) {
- GENCODE1(0x5a);
- PRINTF("pop edx\n");
- GENCODE1(0x5a);
- PRINTF("pop edx\n");
- } else
- if (argn) {
- #if 0
- GENCODE4(0x8d,0x64,0x24,argn);
- PRINTF("lea esp,[esp+%d]\n",argn);
- #else
- GENCODE2i(0x81,0xc4,argn);
- PRINTF("add esp,%d\n",argn);
- #endif
- }
- }
-
- static void jump(void)
- {
- call("jmppc",(funcptr)jmppc,4); /* 5 + 5 */
- GENCODE2(0xff,0xe0); /* 2 */
- PRINTF("jmp eax\n");
- //endflg = 1;
- }
-
- static void jump_imm(UINT32 newpc)
- {
- push_imm(newpc);
- jump();
- }
-
- static void bxx(UINT32 code,UINT32 Pc,char *str,int op)
- {
- UINT32 newpc;
- char *base;
-
- if (FETCH(Pc)==0) {
- /* nop */
- PRINTF("%08x %08x %s\n",(int)Pc,0,"nop");
- } else {
- GENCODE1(0x9c);
- PRINTF("pushf\n");
- compile2(Pc);
- GENCODE1(0x9d);
- PRINTF("popf\n");
- }
-
- GENCODE2(op,0);
- PRINTF("%s @skip\n",str);
- base = pcptr;
-
- newpc = Pc + immS*4;
- #if 0
- if (COMPILED(newpc)) {
- GENCODE1i(0xe9,COMPILED(newpc)-(UINT32)(pcptr+5));
- PRINTF("jmp %p\n",COMPILED(newpc));
- } else
- #endif
- {
- push_imm(newpc); /* 5 */
- jump(); /* 5 + 1 + 2 */
- }
- base[-1] = (UINT32)pcptr-(UINT32)base;
- PRINTF("@skip:\n");
- /*
- push_imm(PC+4);
- jump();
- endflg = 1;
- */
- }
-
- static void store_pc(int pc)
- {
- /* fobOp */
- GENCODE2i(0xc7,0x86,rPC);
- PRINTF("mov dword [esi+%d],0%xh\n",rPC,pc-4);
- PRINTF(" %p %08x\n",pcptr,pc-4);
- *(long*)pcptr = pc-4;
- pcptr+=4;
- }
-
- static void store(UINT32 code,char *str,funcptr func)
- {
- push_r(rt);
- push_addr(code);
- call(str,func,8);
- }
-
- static void load(UINT32 code,char *str,funcptr func)
- {
- push_addr(code);
- call(str,func,4);
- }
-
- void sxx(UINT32 code,char *str,int op_r,int op_m)
- {
- /* 8b 46 xx mov eax,[esi+xx] */
- /* c1 e0 xx shl eax,xx */
- /* c1 e8 xx shr eax,xx */
- /* c1 f8 xx sar eax,xx */
- /* c1 66 xx yy shl [esi+xx],yy */
- /* c1 6e xx yy shr [esi+xx],yy */
- /* c1 7e xx yy sar [esi+xx],yy */
- /* 89 46 xx mov [esi+xx],eax */
-
- int shamt = (code>>6)&31;
- if (rd && shamt) {
- if (rd==rt) {
- GENCODE4(0xc1,op_m,rd,shamt);
- PRINTF("%s dword [esi+%d],%d\n",str,(int)rd,shamt);
- //isimm[rdno] = 0;
- /*if (rd==lastax)*/ lastax = -1;
- } else {
- load_ax(rt);
- GENCODE3(0xc1,op_r,shamt);
- PRINTF("%s eax,%d\n",str,shamt);
- store_ax(rd);
- }
- }
- }
-
- void sxxv(UINT32 code,char *str,int op_r,int op_m)
- {
- /* 8b 46 xx mov eax,[esi+xx] */
- /* 8b 4e xx mov ecx,[esi+xx] */
- /* 8a 4e xx mov cl,[esi+xx] */
- /* d3 e0 shl eax,cl */
- /* d3 e8 shr eax,cl */
- /* d3 f8 sar eax,cl */
- /* d3 66 xx shl [esi+xx],cl */
- /* d3 6e xx shr [esi+xx],cl */
- /* d3 7e xx sar [esi+xx],cl */
- /* 89 46 xx mov [esi+xx],eax */
-
- if (rd && rs) {
- GENCODE3(0x8b,0x4e,rs);
- PRINTF("mov ecx,[esi+%d]\n",(int)rs);
- if (rd==rt) {
- GENCODE3(0xd3,op_m,rd);
- PRINTF("%s dword [esi+%d],cl\n",str,(int)rd);
- /*if (rd==lastax)*/ lastax = -1;
- } else {
- load_ax(rt);
- GENCODE2(0xd3,op_r);
- PRINTF("%s eax,cl\n",str);
- store_ax(rd);
- }
- }
- }
-
- static void cop2gen(cop2func func)
- {
- if (!func) return;
- GENCODE2i(0x8d,0x86,idxCPR2);
- PRINTF("lea eax,[esi+CPR2]\n");
- push_ax();
- call("cop2func",(funcptr)func,4);
- }
-
- int compile1(UINT32 Pc)
- {
- UINT32 code;
- // static char strbuf[256];
-
- if (COMPILED(Pc)) {
- PRINTF("JUMP %x %x %x\n",(int)Pc,(int)pcptr,(int)COMPILED(Pc));
- GENCODE1i(0xe9,COMPILED(Pc)-(UINT32)(pcptr+5));
- PRINTF("jmp %p\n",(void *)COMPILED(Pc));
- Pc+=4;
- endflg = 1;
- return Pc;
- }
-
- if (!in_slot) COMPILED(Pc) = (long)pcptr;
- if (!(FPSE_Flags & SET_ESI)) {
- GENCODE1i(0xBE,(int)®);
- PRINTF("mov esi,reg\n");
- FPSE_Flags |= SET_ESI;
- }
-
- /*
- if (Pc==breakpoint) {
- call("watch",watch,0);
- }
- */
-
- code = FETCH(Pc);
-
- DISASM(code,Pc);
-
- Pc+=4;
- if (code)
- switch(code>>26) {
-
- case SPECIAL:
- switch(code&63) {
- /* c1 e0 xx shl eax,xx */
- /* c1 e8 xx shr eax,xx */
- /* c1 f8 xx sar eax,xx */
- /* c1 66 xx yy shl [esi+xx],yy */
- /* c1 6e xx yy shr [esi+xx],yy */
- /* c1 7e xx yy sar [esi+xx],yy */
-
- case SLL: sxx(code,"shl",0xe0,0x66); break;
- case SRL: sxx(code,"shr",0xe8,0x6e); break;
- case SRA: sxx(code,"sar",0xf8,0x7e); break;
-
- /* d3 e0 shl eax,cl */
- /* d3 e8 shr eax,cl */
- /* d3 f8 sar eax,cl */
- /* d3 66 xx shl [esi+xx],cl */
- /* d3 6e xx shr [esi+xx],cl */
- /* d3 7e xx sar [esi+xx],cl */
-
- case SLLV: sxxv(code,"shl",0xe0,0x66); break;
- case SRLV: sxxv(code,"shr",0xe8,0x6e); break;
- case SRAV: sxxv(code,"sar",0xf8,0x7e); break;
-
- /*
- 03 46 xx add eax,[esi+rt]
- 01 46 xx add [esi+rt],eax
- 2b 46 xx sub eax,[esi+rt]
- 29 46 xx sub [esi+rt],eax
- 23 46 xx and eax,[esi+rt]
- 21 46 xx and [esi+rt],eax
- 0b 46 xx or eax,[esi+rt]
- 09 46 xx or [esi+rt],eax
- 33 46 xx xor eax,[esi+rt]
- 31 46 xx xor [esi+rt],eax
- */
-
- case ADD: alu_r(code,"add",0x03,0x01); break;
- case ADDU: alu_r(code,"add",0x03,0x01); break;
- case SUBU: subu_r(code); break;
- case SUB: subu_r(code); break;
- case AND: and_r(code); break;
- case OR: alu_r(code,"or" ,0x0b,0x09); break;
- case XOR: alu_r(code,"xor",0x33,0x31); break;
- case NOR: nor_r(code); break;
-
- case SLT:
- if (rd==0) break;
- cmp_r(code);
- GENCODE3(0xf,0x9c,0xc0);
- PRINTF("setl al\n");
- GENCODE1i(0x25,1);
- PRINTF("and eax,1\n");
- store_ax(rd);
- break;
- case SLTU:
- if (rd==0) break;
- cmp_r(code);
- GENCODE3(0xf,0x92,0xc0);
- PRINTF("setb al\n");
- GENCODE1i(0x25,1);
- PRINTF("and eax,1\n");
- store_ax(rd);
- break;
- case DIV:
- load_ax(rs);
- GENCODE1(0x99);
- PRINTF("cdq\n");
- GENCODE3(0xf7,0x7e,rt);
- PRINTF("idiv dword [esi+%d]\n",(int)rt);
- store2_ax(idxrLO);
- store2_dx(idxrHI);
- lastax = -1;
- break;
- case DIVU:
- load_ax(rs);
- GENCODE2(0x31,0xd2);
- PRINTF("xor edx,edx\n");
- GENCODE3(0xf7,0x76,rt);
- PRINTF("div dword [esi+%d]\n",(int)rt);
- store2_ax(idxrLO);
- store2_dx(idxrHI);
- lastax = -1;
- break;
- case MULT:
- load_ax(rs);
- GENCODE3(0xf7,0x6e,rt);
- PRINTF("imul dword [esi+%d]\n",(int)rt);
- store2_ax(idxrLO);
- store2_dx(idxrHI);
- lastax = -1;
- break;
- case MULTU:
- load_ax(rs);
- GENCODE3(0xf7,0x66,rt);
- PRINTF("mul dword [esi+%d]\n",(int)rt);
- store2_ax(idxrLO);
- store2_dx(idxrHI);
- lastax = -1;
- break;
- case MFHI: if (rd) { load2_ax(idxrHI); store_ax(rd); } break;
- case MFLO: if (rd) { load2_ax(idxrLO); store_ax(rd); } break;
- case MTHI: load_ax(rs); store2_ax(idxrHI); break;
- case MTLO: load_ax(rs); store2_ax(idxrLO); break;
-
- case JALR:
- store_imm(31*4,Pc+4);
- push_r(rs);
- compile2(Pc);
- jump();
- Pc+=4;
- break;
- case JR :
- endflg = 1;
- push_r(rs);
- compile2(Pc);
- jump();
- Pc+=4;
- break;
- case BREAK:
- push_imm(Pc-4);
- push_imm(E_Bp*4);
- call("exception",(funcptr)exception,8);
- GENCODE2(0xff,0xe0);
- PRINTF("jmp eax\n");
- break;
- case SYSCALL:
- push_imm(Pc-4);
- push_imm(E_Sys*4);
- call("exception",(funcptr)exception,8);
- GENCODE2(0xff,0xe0);
- PRINTF("jmp eax\n");
- break;
- default: NOT_IMPREMENT("special"); break;
- }
- break;
-
- case BCOND:
- switch(rtno){
- case BLTZAL:store_imm(31*4,Pc+4);
- case BLTZ: cmp_i(code,0); bxx(code,Pc,"jge",0x7d); Pc+=4; break;
- case BGEZAL:store_imm(31*4,Pc+4);
- case BGEZ: cmp_i(code,0); bxx(code,Pc,"jl",0x7c); Pc+=4; break;
- default: NOT_IMPREMENT("bcond"); break;
- }
- break;
-
- /* BRANCH/JUMP */
- case J:
- endflg = 1;
- compile2(Pc);
- jump_imm((Pc&0xf0000000)|((code&0x03ffffff)<<2));
- Pc+=4;
- break;
- case JAL:
- store_imm(31*4,Pc+4);
- compile2(Pc);
- jump_imm((Pc&0xf0000000)|((code&0x03ffffff)<<2));
- Pc+=4;
- break;
- case BNE: cmp_r(code); bxx(code,Pc,"je",0x74); Pc+=4; break;
- case BEQ:
- if (rs==0 && rt==0) {
- compile2(Pc);
- jump_imm(Pc+immS*4);
- endflg = 1;
- } else {
- cmp_r(code); bxx(code,Pc,"jne",0x75);
- }
- Pc+=4;
- break;
- case BLEZ: cmp_i(code,0); bxx(code,Pc,"jg",0x7f); Pc+=4; break;
- case BGTZ: cmp_i(code,0); bxx(code,Pc,"jle",0x7e); Pc+=4; break;
-
- /* ALU */
- /*
- 05 ii ii ii ii add eax,imm
- 81 46 xx ii ii ii ii add dword [esi+rt],imm
- 25 ii ii ii ii and eax,imm
- 81 66 xx ii ii ii ii and dword [esi+rt],imm
- 0d ii ii ii ii or eax,imm
- 81 4e xx ii ii ii ii or dword [esi+rt],imm
- 35 ii ii ii ii xor eax,imm
- 81 76 xx ii ii ii ii xor dword [esi+rt],imm
- 3d ii ii ii ii cmp eax,imm
- 81 7e xx ii ii ii ii cmp dword [esi+rt],imm
- b8 ii ii ii ii mov eax,imm
- */
- case ADDI: add_i(code); break;
- case ADDIU: add_i(code); break;
- case ANDI: alu_i(code,"and",0x25,0x66); break;
- case ORI: alu_i(code,"or" ,0x0d,0x4e); break;
- case XORI: alu_i(code,"xor",0x35,0x76); break;
- case LUI:
- {
- UINT32 imm = code<<16;
- if (!in_slot) {
- UINT32 code2 = FETCH(Pc);
- if (((code2>>16)&0x3ff) == ((rtno<<5)|rtno)) {
- switch(code2>>26) {
- case ORI:
- case XORI:
- DISASM(code2,Pc);
- Pc+=4;
- imm |= code2&0xffff;
- break;
- case ADDI:
- case ADDIU:
- DISASM(code2,Pc);
- Pc+=4;
- imm += (INT16)code2;
- break;
- }
- }
- }
- store_imm(rt,imm);
- }
- break;
- case SLTI:
- cmp_i(code,immS);
- GENCODE3(0xf,0x9c,0xc0);
- PRINTF("setl al\n");
- GENCODE1i(0x25,1);
- PRINTF("and eax,1\n");
- store_ax(rt);
- break;
- case SLTIU:
- cmp_i(code,immS);
- GENCODE3(0xf,0x92,0xc0);
- PRINTF("setb al\n");
- GENCODE1i(0x25,1);
- PRINTF("and eax,1\n");
- store_ax(rt);
- break;
-
- /* COP */
- case COP0:
- switch(rsno) {
- case MFC: load2_ax(idxCPR0+rd); store_ax(rt); break; /* MFC */
- case CFC: load2_ax(idxCCR0+rd); store_ax(rt); break; /* CFC */
- case MTC: load_ax(rt); store2_ax(idxCPR0+rd); break; /* MTC */
- case CTC: load_ax(rt); store2_ax(idxCCR0+rd); break; /* CTC */
- case 16:
- if ((code&31)==16) { /* RFE */
- call("rfe",(funcptr)rfe,0);
- break;
- }
- default: NOT_IMPREMENT("COP0"); break;
- }
- break;
- case COP2:
- switch(rsno) {
- case MFC:
- cop2gen(cop2readfuncptr(rdno));
- load2_ax(idxCPR2+rd); store_ax(rt);
- break; /* MFC */
- case CFC:
- cop2gen(cop2readfuncptr(rdno+32));
- load2_ax(idxCCR2+rd); store_ax(rt);
- break; /* CFC */
- case MTC:
- load_ax(rt); store2_ax(idxCPR2+rd);
- cop2gen(cop2writefuncptr(rdno));
- break; /* MTC */
- case CTC:
- load_ax(rt); store2_ax(idxCCR2+rd);
- cop2gen(cop2writefuncptr(rdno+32));
- break; /* CTC */
- default:
- cop2gen(cop2funcptr(code&0x1ffffff));
- break;
- }
- break;
-
- /* LOAD/STORE */
- /*
- 8b 46 xx mov eax,[esi+xx]
- 8b 56 xx mov edx,[esi+xx]
- 03 05 ii ii ii ii add eax,[imm]
- 8b 80 ii ii ii ii mov eax,[eax+imm2]
- 8a 80 ii ii ii ii mov al,[eax+imm2]
- 66 8b ii ii ii ii mov ax,[eax+imm2]
- 0f b6 80 ii ii ii ii movzx eax,byte [eax+imm2]
- 0f b7 80 ii ii ii ii movzx eax,word [eax+imm2]
- 0f be 80 ii ii ii ii movsx eax,byte [eax+imm2]
- 0f bf 80 ii ii ii ii movsx eax,word [eax+imm2]
- 89 80 ii ii ii ii mov [eax+imm2],eax
- 66 89 80 ii ii ii ii mov [eax+imm2],ax
- 88 80 ii ii ii ii mov [eax+imm2],al
- 89 82 ii ii ii ii mov [edx+imm2],eax
- 66 89 82 ii ii ii ii mov [edx+imm2],ax
- 88 82 ii ii ii ii mov [edx+imm2],al
- */
-
- case SB:
- store_pc(Pc);
- #if 0
- { int base;
- if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
- load_dx(rs);
- load_ax(rt);
- GENCODE2i(0x88,0x82,base);
- PRINTF("mov [edx+0%xh],al\n",base);
- break;
- } }
- #endif
- store(code,"write8",(funcptr)write8); break;
- case SH:
- store_pc(Pc);
- #if 0
- { int base;
- if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
- load_dx(rs);
- load_ax(rt);
- GENCODE3i(0x66,0x89,0x82,base);
- PRINTF("mov [edx+0%xh],ax\n",base);
- break;
- } }
- #endif
- store(code,"write16",(funcptr)write16); break;
- case SW:
- store_pc(Pc);
- #if 0
- { int base;
- if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
- load_dx(rs);
- load_ax(rt);
- GENCODE2i(0x89,0x82,base);
- PRINTF("mov [edx+0%xh],eax\n",base);
- break;
- } }
- #endif
- store(code,"write32",(funcptr)write32); break;
- case SWL: store(code,"swl",(funcptr)swl); break;
- case SWR: store(code,"swr",(funcptr)swr); break;
-
- case LB:
- store_pc(Pc);
- #if 0
- { int base;
- if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
- load_ax(rs);
- GENCODE3i(0x0f,0xbe,0x80,base);
- PRINTF("movsx eax,byte [eax+0%xh]\n",base);
- store_ax(rt);
- break;
- } }
- #endif
- load(code,"read8",(funcptr)read8);
- if (rt) {
- GENCODE3(0x0f,0xbe,0xc0); PRINTF("movsx eax,al\n");
- store_ax(rt);
- }
- break;
- case LBU:
- store_pc(Pc);
- #if 0
- { int base;
- if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
- load_ax(rs);
- GENCODE3i(0x0f,0xb6,0x80,base);
- PRINTF("movzx eax,word [eax+0%xh]\n",base);
- store_ax(rt);
- break;
- } }
- #endif
- load(code,"read8",(funcptr)read8);
- store_ax(rt);
- break;
- case LH:
- store_pc(Pc);
- #if 0
- { int base;
- if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
- load_ax(rs);
- GENCODE3i(0x0f,0xbf,0x80,base);
- PRINTF("movsx eax,word [eax+0%xh]\n",base);
- store_ax(rt);
- break;
- } }
- #endif
- load(code,"read16",(funcptr)read16);
- if (rt) {
- GENCODE3(0x0f,0xbf,0xc0); PRINTF("movsx eax,ax\n");
- store_ax(rt);
- }
- break;
- case LHU:
- store_pc(Pc);
- #if 0
- { int base;
- if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
- load_ax(rs);
- GENCODE3i(0x0f,0xb7,0x80,base);
- PRINTF("movzx eax,word [eax+0%xh]\n",base);
- store_ax(rt);
- break;
- } }
- #endif
- load(code,"read16",(funcptr)read16);
- store_ax(rt);
- break;
-
- case LW:
- store_pc(Pc);
- #if 0
- { int base;
- if (isimm[rsno] && (base = (int)baseaddr2(isimm[rsno]+immS)+immS)!=0) {
- load_ax(rs);
- GENCODE2i(0x8b,0x80,base);
- PRINTF("mov eax,[eax+0%xh]\n",base);
- store_ax(rt);
- break;
- } }
- #endif
- load(code,"read32",(funcptr)read32);
- store_ax(rt);
- break;
- case LWL:
- push_r(rt);
- push_addr(code);
- call("lwl",(funcptr)lwl,8);
- store_ax(rt);
- break;
- case LWR:
- push_r(rt);
- push_addr(code);
- call("lwr",(funcptr)lwr,8);
- store_ax(rt);
- break;
- case SWC0:
- push2_r(rt+idxCPR0);
- push_addr(code);
- call("write32",(funcptr)write32,8);
- lastax = -1;
- break;
- case LWC0:
- load(code,"read32",(funcptr)read32);
- store2_ax(rt+idxCPR0);
- break;
- case SWC2:
- cop2gen(cop2readfuncptr(rtno));
- push2_r(rt+idxCPR2);
- push_addr(code);
- call("write32",(funcptr)write32,8);
- lastax = -1;
- break;
- case LWC2:
- load(code,"read32",(funcptr)read32);
- store2_ax(rt+idxCPR2);
- cop2gen(cop2writefuncptr(rtno));
- break;
- default: NOT_IMPREMENT("??"); break;
- }
- return Pc;
- }
-
- #if 0
- int compiled(UINT32 Pc)
- {
- return COMPILED(Pc);
- }
-
- void compile(UINT32 Pc)
- {
- if (COMPILED(Pc)) return;
- pcbase = baseaddr(Pc);
- endflg = 0;
- memset(isimm,0,sizeof(isimm));
- while(!endflg) {
- Pc = compile1(Pc);
- }
- }
-
- #endif